iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0
自我挑戰組

從零開始全端實作 Express.js + TypeScript + DevOps 系列 第 10

【Day 10】CSS 歷史與語法介紹(2)CSS2 後續發展

  • 分享至 

  • xImage
  •  

點我查看目錄

更前言

上週在操作 Conda 的時候,不小心把系統的 Python3 炸了,所以我花了一點時間處理 Linux 系統的問題,然後吃晚餐又不小心食物中毒,所以也就這樣斷賽並且延宕了不少進度,因此接下來就只能慢慢補回來囉!

前言

在前一章中,我們提到了 CSS 1 過渡到 CSS 2 的過程,這轉變出自於當時的 CSS 1 在實做上的諸多限制、以及 IE 與 Ntescape 之間的戰爭。但網頁設計的需求也隨著時間推移變得越來越複雜,CSS 1 在實際應用上顯現出許多不足之處,特別是在版面設計的控制、多平台(裝置)支援的能力、瀏覽器之間的相容性等方面。也正因因此讓 W3C 推出 CSS 2 以作為 CSS 1 的擴充版本來試圖解決這些問題。那接下來,就會來探討 CSS 2 在語法上做了哪些擴充。

瀏覽器戰爭破局

在前面我們提到,1990 年代末期時的瀏覽器市場的競爭以 NetscapeIE 之間的角力最為激烈。這被稱為**「瀏覽器戰爭」**不僅是在搶佔市佔率,而是更延伸到技術層面各自推出專屬技術,也因此冷落了 W3C 所制定的網頁標準,其中就包含 CSS。

Netscape 希望透過屬於自己的 Layer(圖層)技術來統治網頁設計,而 Microsoft 則試圖推廣 ActiveX 和 VBScript。結果,這兩家公司的對抗讓就直接讓 CSS 1 成為一個「被孤立」的標準,設計師只能勉強在 IE 和 Netscape 之間找尋平衡,甚至為不同的瀏覽器寫兩套樣式表

這對網頁工程師來說就是非常棘手的事情了,他們為了讓網頁能在不同瀏覽器上正常顯示,就得量身打造 CSS,例如 Netscape Navigator 推出了如 Netscape Layer 等專屬功能,而 IE 則是大力推廣ActiveX 之類的技術,這光看了就覺得挺麻煩的。

這局面也讓 W3C 十分頭痛,因此 CSS 2 的主要目標就是要統一瀏覽器之間的相容性問題,不再受到個別瀏覽器的牽制,所以這理念就貫穿了整個 CSS 2 的設計過程:「制定統一標準使得不同瀏覽器的渲染行為趨於一致。」

CSS 2 與 2.1 的功能擴充


然而在查閱 W3C 在 1998 年的官方文件後,你就會發現在 CSS 2.1 與 2 幾乎繼承了 CSS 1 的語法和功能,幾乎沒有什麼語法被標記為 Deprecated(廢棄)。因此我們可以將 CSS 2 視為解決 CSS 1 語法不足的擴充版本;而 CSS 2.1 亦為 CSS 2 的擴充版本。而是事實上每一代 CSS 都是如此,很多在 HTML 中被棄用的樣式語法都跑來 CSS 中了。上一篇文末有提到 CSS 1 對網頁工程師造成的困擾,因此 CSS 2.1 便有針對以下進行改進:

A. 浮動與清除(Float & Clear)

在早期網頁設計的圖文排版一直都是棘手的問題,當時只能用 <table> 插入圖片跟表格,但在 CSS 2 中就引入了 float 屬性讓文章能和其他內容可以圍繞元素浮動到兩側。基本上這就解決了當時的 HTML 表格佈局,讓畫面簡單多了。

img {
  float: left;
}

在你處理 float 之後,如果你沒有處理下一個元素,就可能會卡在浮動的元素旁邊。因此這時候你就要用 clear 屬性來清除浮動的影響,讓下一個元素可以回到正常的排版中顯示。

p {
  clear: both;
}

B. 字體屬性的增強

CSS 2 主要是增加一些對字體的控制:

  1. font-variant 能將字母顯示為小型大寫字母(small caps),主要在顯示期刊文章或新聞文章時,會常用來強調一些標題或重要段落。

    p {
      font-variant: small-caps;
    }
    
  2. font-stretch 能對字體進行水平方向的壓縮或延伸,可以在你要設計頁面佈局,能將字體稍微拉長或壓縮,就不須要用插入圖片來達成這效果了。

    p {
      font-stretch: expanded;
    }
    
  3. 字體屬性縮寫font 屬性是 CSS 2 的0縮寫語法之一,你可以把 font-familyfont-sizefont-weightfont-style 寫在同一行。

    p {
        font: bold 16px Arial, sans-serif;
    }
    
  4. 然而,並非所有的字體屬性都能適應時代的發展需求。例如,CSS 1 中的 text-decoration: blink 屬性曾經讓文字可以閃爍,雖然這在當時是一個有趣的特效,但在現代瀏覽器中,這種效果已經逐漸被棄用,因為它被認為對使用者體驗不佳。

C. 更強的背景控制

在當年的網頁設計中,背景圖片呈現的設計是創造視覺效果的重要方式之一。在 CSS 1 時期的網頁工程師只能單純呈現背景圖片,你只能在一個超長內文的網頁中設計一個相對長的圖片來處理、或是直接設定為單色調或留白,但在 CSS 2 就是可以放一張符合螢幕解析度(例如 1280*960)的圖片就可以了:

  1. background-attachment 可以設定背景圖片是保持固定、還是隨著頁面滾動。在當年這可是網頁工程師炫技的手法之一。

    body {
      background-attachment: fixed;
    }
    
  2. 那如果你的圖片比較小,須要讓背景圖片可以重複顯示並寫填滿整個頁面,這時就可以用 background-repeat 來設定了

    body {
      background-repeat: no-repeat;
    }
    

D. 盒模型的增強

CSS 2 直接解決了當年 Box Model 在不同瀏覽器中實現的差異,而你也可以把定義邊界的語法寫在同一行裡面

  1. marginpadding 的細緻控制:在 CSS 2.1 中,網頁工程師可以為每個方向(依序為上、右、下、左)單獨設定邊外邊距離和內框距離,你就發現在邊界控制上就可以很精確了。同時paddingborder 不再計入元素的總寬度,所以布局上就可以針對需求進行逐項控制了。

    p {
        width: 300px;
        margin: 10px 20px 30px 40px;
        padding: 40px 30px 20px 10px;
        border: 5px solid black;
    }
    
  2. 除此之外,CSS 2.1 還對 overflowvisibility、以及 white-space 這三個屬性進行強化,其中 overflow 主要用來控制當內容超出容器邊界時的處理方式; visibility 則是用來顯示或隱藏一些元素;而 white-space 用來設定文章是否要強制換行。

    div {
        overflow: scroll; 
        visibility: hidden;
    }
    
    p {
        white-space: nowrap;
    }
    

E. 表格樣式控制的增強

CSS 2 大幅強化了表格的樣式控制,針對 CSS1 在呈現上的不一致進行修正。table-layout 在處理多行或多列資料時,可以解決因為 &lt;table&gt; 的預設行為導致不同裝置或瀏覽器在顯示上的差異;而 table-layout: fixed 就可以固定行寬;此外 border-collapseborder-spacing 可以控制表格邊框和每一格(Grid / Cell)的間距。

table {
    border-collapse: collapse;
    border-spacing: 5px;
    table-layout: fixed;
}

F. 定位模型(Positioning Model)

有時候我們會希望一些內容被呈現在固定的地方,因此 CSS 2 推出了全新的 Positioning Model,定義 position 屬性來控制一個元素的顯示位置,可以分為絕對定位absolute)、相對定位relative)和固定定位fixed),這樣就擺脫靠表格處理的痛苦過程了。

div {
	  position: absolute;
	  top: 50px;
	  left: 100px;
}

p {
		position: relative;
		top: -15px;
		right: 5px;
}

G. 排版功能

很多時候,你會發現一些老舊網頁的內容,在現今的大螢幕下,會出現間隔過大的問題,那現在的網頁教不會出現這情況,是因為排版功能幫我們把內容控制在一個範圍裡面,包含寬度(min-widthmax-width)與高度(min-heightmax-height)。這樣內容在內容較多或少時、或是螢幕過大時,可以不讓網頁呈現直接走樣,這也是 CSS 3 裡面做互動設計中的重點基礎。

div {
    min-width: 200px;
    max-width: 500px;
    min-height: 100px;
    max-height: 300px;
}

H. 媒體查詢與設備支援

當年會使用瀏覽器的裝置逐漸不只是瀏覽器,當年歐美很流行的 PDA 與一些印表機裝置等,甚至是早期的語音瀏覽器都會被用來上網。在當時的 CSS 1 是靜態的,這些設備查看網頁時就只能用電腦版呈現的網頁,當時只能靠單獨設計專屬的網頁架構、或使用大量的 JavaScript 來解決這問題。

直到 CSS 2 引入了 Media Queries(媒體查詢)的語法 @media,讓網頁工程師可以根據不同的裝置設定不同的顯示樣式,這樣你就可以用同一組 CSS 針對不同的裝置來設計 CSS 內的參數即可。例如當使用者要列印網頁時,網頁工程師可以選擇隱藏導航欄、圖片等不必要的元素等。

@media print {
  body {
    font-size: 12px;
  }
}

J. 強化的 Selector

在 CSS 1 時代的選擇器使用範圍非常有限,設計師只能透過幾種基礎選擇器來操作網頁上的元素。當時能用的選擇器僅包含:

  1. 元素選擇器(Element Selector):只能選擇單一類型的 HTML 標籤,例如 ph1
  2. 類別選擇器(Class Selector):使用 . 符號來選擇帶有特定 class 屬性的元素,例如 .title
  3. ID 選擇器(ID Selector):使用 # 符號來選擇唯一的 ID 屬性元素,例如 #header
  4. 群組選擇器(Group Selector):可以一次為多個標籤設定相同樣式,如 h1, h2, h3 { color: blue; }

即便是這幾種簡單的選擇器,在當時卻讓設計師感到非常吃力。你可以想像,如果要針對同一類型標籤中的某些特定元素設定樣式,你會發現根本無法精確操作,設計師只能想盡辦法在每個元素中手動增加 class 或 ID,才能勉強達成目的。

舉個例子,如果你想改變列表中第二個項目的背景顏色,你會發現自己無從下手,因為 CSS1 根本沒有針對特定順序的選擇器,只能使用類似 <li class="second-item"> 這種方式來標記每個元素。當列表項目很多時(例如 20 個),這樣的做法沒意外就是將 樣式 與 結構 全擠在一塊,你過一陣子回來看就會發現看不懂自己的文章了。也正因如此, CSS 2 主要就針對以下三個進行強化

  1. Structural Pseudo-classes(結構性偽類選擇器)讓我們可以直接控制要改變的樣式。

    例如你可以用 :first-child 來選取父容器中第一個子元素。這讓你就不需要再手動給第一個元素加上特定 class 或 ID,就能針對第 n 個元素進行樣式調整。例如:

    p:first-child {
        font-weight: bold;
    }
    
    /* Or alternatively for the (n)-th child: */
    
    li:nth-child(even) {
        background-color: lightgray;
    }
    

    你可以發現這個 Selector 基本上直接改變你處理列表的邏輯、無論是表格和多行段落的方式,你都可以針對每個奇數項還是偶數項設定不同樣式,一切都變得十分簡單。

  2. Attribute Selectors(屬性選擇器)

    這一變化對於表單元素(如 input)的操作來說會變得相當便利。舉例來說,一個 基本屬性選擇器 可以選取擁有特定屬性的元素。例如你可以只選取所有 type="text" 的輸入框,而其他類型的輸入框就不會被影響;或是僅選取所有 href 屬性中有包含 "example" 的網址的元素:

    input[type="text"] {
        border: 1px solid black;
    }
    
    a[href*="example"] {
        color: blue;
    }
    
  3. Psuedo-classes 與 Psuedo-elements(偽類與偽元素)

    當時我看到這名詞的時候,真的是滿頭問號,想說這要「偽」什麼?後來才發現「虛擬類別」可能會比較好理解。這名詞是來自於,你會希望使用者執行一些行為時,可以對特定狀態的元素或特定位置進行樣式控制,但不是真正產生新的 Class 或 Element。也就是說,這些「虛構的」 Class 或 Elements 是直接基於現有元素上直接改變,而不必去改變 HTML 的結構,也不需要另外用 JavaScript 去控制。

    • :hover:focus:active:這些 Psuedo Selector 讓可以讓你在一些使用者操作上進行樣式改變。舉例來說,當使用者的滑鼠游標停留在連結上時,連結的顏色就能自動改變,而且不需要額外撰寫 JavaScript 去控制了。

      例如:

      a:hover {
        color: red;
      }
      
      input:focus {
          border: 2px solid blue;
      }
      
    • ::before::after:這就是在元素的前後插入一些元素,而你不用改變 HTML 結構。舉例來說,你可以在一些超連結前面加入一些 Icon 等。

      p::before {
          content: "Start:";
          font-weight: bold;
      }
      
      p::after {
          content: " End";
          font-style: italic;
      }
      
      button:hover::before {
          content: "👉 ";
      }
      
      button:hover::after {
          content: " 👈";
      }
      

    在你實做之後就會發現,Psuedo-class 的呈現就是我們習以為常的視覺技術,我們不需要撰寫太多的 JavaScript 就可以讓網頁使用上有很大的視覺效果。

K. 伺服器端與語音樣式

當年 CSS 2 規範中引入的「伺服器端與語音樣式」功能,當時實際上是設計給不同類型的設備用的,包括 PDA、印表機、以及語音瀏覽器,主要是讓網站可以將網站轉換為語音後朗讀出來。開發者可以針對語音設備(例如合成器)來調整內文被閱讀的順序、語速、音量…等。但由於瀏覽器的支援度較低,且這些語音設備還沒有被普及,所以大部分的語音屬性在 CSS 2.1 時就被移除了。


總結

你會發現 CSS 跟 HTML 就是相輔相成的,而且 W3C 也在這過程中盡可能分離「架構」與「樣式」之間的分工,所以我們在實務操作上就會盡可能分離這些內容。而你在開發過程中,就會發現有些樣式會經常被重複使用到,你就會想要如何讓這些過程便得更加簡單?那我們就會用「框架」了,例如 Bootstrap 或 Tailwind。但我不建議一開始就學框架,因為你要知道原始的 CSS 是如何被架構出來的、而後才會知道框架可以直接幫我們解決哪些問題,在使用框架遇到一些問題後,才會知道如何正確的 Debug。總之,後續我們就會開始正式實做了。


上一篇
【Day 09】CSS 歷史與語法介紹(1)HTML 與 CSS 的配合
下一篇
【Day 11】CSS 歷史與語法介紹(3)CSS 3 與設計打磚小蜜蜂遊戲的外觀與界面
系列文
從零開始全端實作 Express.js + TypeScript + DevOps 12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言